/****************************************************************************************************************************
 * @File name:test_seq.c
 * @Author:sunshu
 * @Version:v1.00
 * @Date:2018/01/20
 * @Description:
 * @Others:
 * @Function List:
 * @History:
****************************************************************************************************************************/
#include "test_seq.h"
#include "ads1115.h"
#include "elec_sw.h"
#include "delay.h"
#include "command.h"
#include "usart.h"
#include "short_test.h"
#include "cap_test.h"

// Define Threshold (default)
#ifdef _REF3V3
#define	Threshold1	300
#define	Threshold2	550
#define	Threshold3	762
#define	Threshold4	943
#define	Threshold5	1100
#define	Threshold6	1238
#define	Threshold7	1359
#define	Threshold8	1467
#define	Threshold9	1563
#define	Threshold10	1650

#elif _REF2V5
#define	Threshold1	227
#define	Threshold2	417
#define	Threshold3	577
#define	Threshold4	714
#define	Threshold5	833
#define	Threshold6	938
#define	Threshold7	1029
#define	Threshold8	1111
#define	Threshold9	1842
#define	Threshold10	1250
#endif

uint8_t TmpStr[50];
uint8_t IsDelay = 0;
extern uint32_t Time0;
extern uint32_t USCount100;
/**
 * @function name:	DividerVaule
 * @brief	Calculate Resistor (rough)
 * @param	Vin -- Voltage input (mV)
 * @return	Res value, unit: 0.1Ω
 * @author	Tom Sum
 * @date	Dec. 5th, 2016
**/

//unit: 1k
//#define K_10K (245.895675974557)
//#define B_10K (-0.0977235117509)

//unit: 1k
//#define K_100K (24.6684)
//#define B_100K (-0.0099)


//#define K_1M (2.415169686016759)
//#define B_1M (-0.000988147662522)
//Unit: 0.01 K
//#define A_1M_2	(0.09291578599996710)
//#define B_1M_2	(-45.3235184805687)
//#define C_1M_2	(25915.35698036060)

//#define A_10M	(0.002933540989707)
//#define B_10M	(4.593307886247817)
//#define C_10M	(-18.163488690940071)
//#define THOLD_100K

#define VolVal_F	((double)VolVal)
#define VolVal_F_2 ((double)(VolVal*VolVal))

#define Adc2Vol_DIV(AdcVal)	((uint32_t)(AdcVal) * ADC_FULL_SCALE >> 15)

uint8_t ABS_u16(uint16_t* dat)
{
    if(*dat>0x7fff)
    {
        *dat=0xffff - (*dat - 1);
        return 1;	//-
    }

    return 0;		//+
}

/****************************************************************************************************************************
* @Functions:DividerResVal()
* @Description:test res which it's value is larger than 10k
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
float DividerResVal(uint8_t sel)
{
    float res=0.0,tmp=0;
    uint16_t AdcVal;
    uint16_t i =0;

    PP2V5_EN();
    CUR_2_0V_EN();																									//2.5-2=0.5v
    DISCHG_RIGHT_OFF();
    DISCHG_LEFT_OFF();
    Delay_us(10);

//	MeasuringSwitch(6);
//	delay_ms(50);

    MeasuringSwitch(sel);
    delay_ms(150);
    ADS1115_GetADC(&UserI2c1,AIN0_AIN1,&AdcVal,ADS1115_ADDR_MES); 		//gain 20  u75
    //ADS1115_GetADC(&UserI2c1,AIN2_AIN3,&AdcVal,ADS1115_ADDR_MES); 	//gain 1  u76

//	printf("1 0.5uA GAIN 20:%d\r\n", AdcVal);
    if(AdcVal<586 || AdcVal>= 0x7fff)
    {
        if( AdcVal < (65535 - 586))
        {
            delay_ms(200);
            ADS1115_GetADC(&UserI2c1,AIN0_AIN1,&AdcVal,ADS1115_ADDR_MES);
            ABS_u16(&AdcVal);
//            printf("2 0.5uA GAIN 20:%d\r\n", AdcVal);
        }
        else
        {
            res=0;
            return res;
        }
    }

    if(AdcVal>9500)//200k~3M
    {
Loop1M:
        delay_ms(30);
        tmp=0;
        for(i=0; i<7; i++)
        {
            //ADS1115_GetADC(&UserI2c1,AIN2_AIN3,&AdcVal,ADS1115_ADDR_MES); 	//gain 1  u76
            ADS1115_GetADC_10KUP(&UserI2c1,AIN2_AIN3,&AdcVal,ADS1115_ADDR_MES); 	//gain 1  u76
            ABS_u16(&AdcVal);
//            printf("1 0.5uA GAIN 1:%.03f mV\r\n", (float)AdcVal*6144/32768);
            if(AdcVal>8000)																								//1.5v
            {
                //AdcVal=8000;
                res = RES_MAX;
            }
            else
            {
                res=(float)AdcVal*6144/32768/0.5f;															//actual current is 0.5uA
                res *= 1000;
            }
            if(tmp!=0)
            {
                if(res/tmp < 1.2f)
                {
                    break;
                }
            }
            else
            {
                tmp=res;
            }

//			sprintf(TmpStr,"200k~3M %f\n",res);
//			UartPushTxBuffer(TmpStr);
//			UsartSendStart();
//			delay_ms(10);
        }
    }
    else if(AdcVal<=9500 && AdcVal>=586)																	//10k~200k
    {
        delay_ms(30);
        ADS1115_GetADC_10KUP(&UserI2c1,AIN0_AIN1,&AdcVal,ADS1115_ADDR_MES); 	//gain 20  u75
        ABS_u16(&AdcVal);
//        printf("3 0.5uA GAIN 20:%.03f mV\r\n", (float)AdcVal*6144/32768/20);
        res=(float)AdcVal*6144/32768/20/0.5f;													//actual current is 0.5uA
        res *= 1000;

        if (res >= 200000) //200k
        {
            goto Loop1M;
        }
    }
    else																															//<10k
    {
        res=0;
    }

    return res;
}


/**
 * @function name:	SRCResVal
 * @brief	Calculate Resistor (accurate)
 * @param	Vin -- Voltage input (mV)
 * @return	Res value, unit: 0.1Ω
 * @author	Tom Sum
 * @date	Dec. 5th, 2016
**/
#define K_5MA 207
#define B_5MA -3710
#define THOLD_5MA 100

#define K_500UA 2027
#define B_500UA -5570
#define THOLD_500UA 3

#define K_50UA 20083
#define B_50UA -2962
#define THOLD_50UA 1

//#define K_100K (24.6791)
//#define B_100K (-0.01)
//#define THOLD_100K

#define Adc2Vol_SRC(AdcVal)	((uint32_t)AdcVal * ADC_FULL_SCALE *10 >>15)

/****************************************************************************************************************************
* @Functions:SRCResVal()
* @Description:test res which it's value is less than 10k
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
float SRCResVal(unsigned char sel)
{
    unsigned short AdcVal=0;
    unsigned long VolVal=0;
    float res;

    if (sel <4 || sel >6) return 0xff; 	// error
    PP2V5_EN();
    CUR_0_5V_EN();											//2.5v-0.5v=2.0v
    MeasuringSwitch(sel);

    delay_ms(30);
    ADS1115_GetADC_SRC(&UserI2c1, AIN2_AIN3, (uint16_t *)&AdcVal,ADS1115_ADDR_MES);					//gain = 1
//	printf("GAIN 1:%d\r\n", AdcVal);
    ABS_u16(&AdcVal);
    VolVal = Adc2Vol_SRC(AdcVal);
//	printf("GAIN 1:%d mV\r\n", VolVal/10);

    if(VolVal<2000)											//<200mV
    {
        delay_ms(10);
        ADS1115_GetADC_SRC(&UserI2c1, AIN0_AIN1, (uint16_t *)&AdcVal,ADS1115_ADDR_MES);				//gain = 20
        ABS_u16(&AdcVal);
        VolVal = Adc2Vol_SRC(AdcVal);			//unit: 0.1 mV
        VolVal = VolVal * 10 / INA1_GAIN;
//    	printf("GAIN 20:%d mV\r\n", VolVal/10);
    }

    if( VolVal <= 52 && sel != 4)	return 0;//50uA* 100Ω = 5mV and for 0.1 ~10 Ohm range is exceptional

    if( sel == _50UA )									//100~10kOhm
    {
        res = (float)VolVal * K_50UA + B_50UA;
        res /= 10000;
    }
    else if( sel == _500UA)							//10~100Ohm
    {
        res = (float)VolVal * K_500UA + B_500UA;
        res /= 10000;
    }
    else if( sel == _5MA)								//1~10Ohm
    {
//		if( VolVal <= THOLD_5MA) return 0;
        if(VolVal > 20000) /* open 2000 mV */
        {
            res = RES_MAX;
        }
        else if(VolVal >= THOLD_5MA)
        {
            res = (float)VolVal * K_5MA + B_5MA;
            res /= 10000;
        }
        else if((30 < VolVal) && (VolVal < THOLD_5MA))
        {
            res = VolVal / 50;
        }
        else
        {
            res = 0;
        }
    }
    return res;
}

/****************************************************************************************************************************
* @Functions:ResCalc()
* @Description:Res calculation in short test
* @Input:CalParam -- Vector of calibration params
* @Output:
* @Return:res value
* @Others:
* @History:
****************************************************************************************************************************/
float ResCalc(void* pParam)
{
    float res=0;

    res=DividerResVal(_0_5UA);  //10k~2M
    if(res != 0) return res;

    // set res switch from 10Ω to 1KΩ to detect proper scale
    /* current source */
    // Select 50uA scale 100Ω - 10k
    res = SRCResVal(_50UA);
    if(res != 0) return res;

    // Select 500uA scale 10Ω - 100Ω
    res = SRCResVal(_500UA);
    if(res != 0) return res;

    // Select 5000uA scale 1Ω - 10Ω
    res = SRCResVal(_5MA);
    return res;
}

/****************************************************************************************************************************
* @Functions:ResCalc_10ohm()
* @Description:test 1Ω - 10Ω
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
float ResCalc_10ohm(void* pParam)
{
    float res=0;
    res = SRCResVal(_5MA);
    return res;
}

/****************************************************************************************************************************
* @Functions:ResCalc_Ra()
* @Description:test 10Ω - 10k
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
float ResCalc_Ra(void* pParam)
{
    float res=0;
    res = SRCResVal(_50UA);
    return res;
}

/****************************************************************************************************************************
* @Functions:PinNum_Gen()
* @Description:turn char-type into string
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
static uint8_t PinNum_Gen(uint8_t Index, uint8_t * PinNumStr)
{
    if(Index>23) 	return 1;
    else if( Index <= 11)	sprintf((char*)PinNumStr,"a%d",Index+1);
    else	sprintf((char*)PinNumStr,"b%d",Index-11);
    return 0;
}

/****************************************************************************************************************************
* @Functions:UartResultPrint()
* @Description:output res value
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
uint8_t UartResultPrint(uint8_t Index,	uint8_t First, uint8_t Second, uint32_t Res)
{
    if(DebugFlag == 0)
        return 0;

    uint8_t PinNum1[4]= {0};
    uint8_t	PinNum2[4]= {0};

    PinNum_Gen(First,	 PinNum1);
    PinNum_Gen(Second, PinNum2);
    sprintf((char*)TmpStr, "%d.	%s,	%s	R=	%d.%d Ohm\n", Index, PinNum1, PinNum2, Res/10, Res%10);
    USART_printf(TmpStr);
    delay_ms(10);

    return 1;
}

/****************************************************************************************************************************
* @Functions:SRC_Set()
* @Description:set current to dedicated channel
* @Input:
ch1 : channel to +
ch2 : channel to -
input : L/R
sel : current value
opt : 1: set sense others: don't set
* @Output:
* @Return:Res value, unit: 0.1Ω
* @Others:
* @History:
****************************************************************************************************************************/
uint8_t SRC_Set(uint8_t ch1, uint8_t ch2, uint8_t input, uint8_t sel,uint8_t opt)
{
    Short_TestCycle.Init();

    Short_TestCycle.ForceSet(ch1,ch2,input);
    if(opt == 1)
        Short_TestCycle.SenseSet(ch1,ch2,input);
    //	Short_TestCycle.SenseSet(ch2,ch1,input);
    else	// connect to NC
        Short_TestCycle.SenseSet(48,48,input);
    if (sel <4 || sel >7) return 0xff; // error
    delay_ms(10);
    PP2V5_EN();
    CUR_0_5V_EN();			//2.5v-0.5v=2.0v
    MeasuringSwitch(sel);
    Short_TestCycle.EnaleSet(1);

    return 1;
}

/****************************************************************************************************************************
* @Functions:Diode_Vdrop()
* @Description:measure diode forward voltage
* @Input:
ch1 : channel to +
ch2 : channel to -
input : L/R
* @Output:
* @Return:Vdrp value, unit: 1 mV
* @Others:
* @History:
****************************************************************************************************************************/
uint32_t Diode_Vdrop(uint8_t ch1, uint8_t ch2, uint8_t input, uint8_t sel)
{
    uint32_t VolVal = 0;
    uint16_t AdcVal;
    SRC_Set(ch1, ch2, input, sel, 1);				//500UA,Sense enable
    delay_ms(50);
    ADS1115_GetADC(&UserI2c1, AIN2_AIN3, &AdcVal,ADS1115_ADDR_MES);
//	if(AdcVal >= 0x8000)
//	{
//		AdcVal = 0xffff - AdcVal;
//	}
    VolVal = Adc2Vol_DIV(AdcVal);					// Unit:  1 mV
    Short_TestCycle.Init();
    return VolVal;
}

/****************************************************************************************************************************
* @Functions:Amux_Enable()
* @Description:set current to dedicated channel
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
void Amux_Enable(uint8_t IsEn)
{
    if(IsEn)
    {
        Short_TestCycle.EnaleSet(1);
    }
    else
    {
        Short_TestCycle.EnaleSet(0);
    }
}


/****************************************************************************************************************************
* @Functions:TimestampPrint()
* @Description:printf testing time
* @Input:
* @Output:
* @Return:
* @Others:
* @History:
****************************************************************************************************************************/
//uint32_t TimestampPrint(uint8_t * Str)
//{
//	#ifdef _TIME_PRINT
//	unsigned long TimStart, TimEnd, TimDelta;
//
//	TimStart = USCount100;
//	TimDelta = (USCount100-Time0)/100;	//10ms
//	sprintf(TmpStr,"[%d.%02d s] %s", TimDelta/100, TimDelta%100, Str);
//	UartPushTxBuffer(TmpStr);
//	UsartSendStart();
//	return TimStart;
//	#endif
//}



